using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;

namespace Util.DataBase
{
    public interface IDbContext<T> where T : class, new()
    {
        /// <summary>
        /// 开始事务
        /// </summary>
        void BeginTran();

        /// <summary>
        /// 提交事务
        /// </summary>
        void CommitTran();

        /// <summary>
        /// 回滚事务
        /// </summary>
        void RollbackTran();

        /// <summary>
        /// 获得简单数据上下文
        /// </summary>
        /// <returns></returns>
        SimpleClient<T> GetSimpleClient();

        /// <summary>
        /// 获得数据上下文
        /// </summary>
        /// <returns></returns>
        SqlSugarClient GetClient();

        /// <summary>
        /// 创建查询实体
        /// </summary>
        /// <returns></returns>
        ISugarQueryable<T> CreateQueryable();

        /// <summary>
        /// 根据键值获得数据
        /// </summary>
        /// <param name="id">键值</param>
        /// <returns></returns>
        T GetById(dynamic id);

        /// <summary>
        /// 获得单个实体信息（如果多于一个，会报错）
        /// </summary>
        /// <param name="whereExpression">条件</param>
        /// <returns></returns>
        T GetSingle(Expression<Func<T, bool>> whereExpression);

        /// <summary>
        /// 获得所有数据信息
        /// </summary>
        /// <returns></returns>
        List<T> GetList();

        /// <summary>
        /// 按指定条件获得数据
        /// </summary>
        /// <param name="whereExpression">条件</param>
        /// <returns></returns>
        List<T> GetList(Expression<Func<T, bool>> whereExpression);

        /// <summary>
        /// 按指定条件获得分页数据
        /// </summary>
        /// <param name="whereExpression">条件</param>
        /// <param name="pm">分页信息</param>
        /// <returns></returns>
        List<T> GetPageList(Expression<Func<T, bool>> whereExpression, PageModel pm);

        /// <summary>
        /// 按指定条件获得分页数据
        /// </summary>
        /// <param name="whereExpression">条件</param>
        /// <param name="pm">分页信息</param>
        /// <param name="orderByExpression">排序条件</param>
        /// <param name="orderByType">排序方向</param>
        /// <returns></returns>
        List<T> GetPageList(Expression<Func<T, bool>> whereExpression, PageModel pm, Expression<Func<T, object>> orderByExpression = null, OrderByType orderByType = OrderByType.Asc);

        /// <summary>
        /// 按指定条件获得分页数据和总记录数
        /// </summary>
        /// <param name="queryable">查询条件</param>
        /// <param name="pm">分页信息</param>
        /// <returns></returns>
        Tuple<List<T>, int> GetPageListAndTotal(ISugarQueryable<T> queryable, PageModel pm);

        /// <summary>
        /// 获得指定条件的数据数量
        /// </summary>
        /// <param name="whereExpression">条件</param>
        /// <returns></returns>
        int GetCount(Expression<Func<T, bool>> whereExpression);

        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="model">实体信息</param>
        /// <returns></returns>
        bool Insert(T model);

        /// <summary>
        /// 插入数据并返回自动生成的键值
        /// </summary>
        /// <param name="model">数据实体</param>
        /// <returns></returns>
        int InsertReturnIdentity(T model);

        /// <summary>
        /// 指插入数据
        /// </summary>
        /// <param name="models">实体信息集</param>
        /// <returns></returns>
        bool Insert(List<T> models);

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="model">实体信息</param>
        /// <returns></returns>
        bool Update(T model);

        /// <summary>
        /// 批量更新数据
        /// </summary>
        /// <param name="models">实体信息</param>
        /// <returns></returns>
        bool UpdateRange(List<T> models);

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="columns">指定要更新的字段</param>
        /// <param name="model">实体信息</param>
        /// <returns></returns>
        int UpdateIncludeColumns(T model, params string[] columns);

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="columns">指定不要更新的字段</param>
        /// <param name="model"></param>
        /// <returns></returns>
        int UpdateExcludeColumns(T model, params string[] columns);

        /// <summary>
        /// 按键值删除数据
        /// </summary>
        /// <param name="id">键值</param>
        /// <returns></returns>
        bool Delete(dynamic id);

        /// <summary>
        /// 按键值删除数据
        /// </summary>
        /// <param name="ids">键值</param>
        /// <returns></returns>
        bool Delete(dynamic[] ids);

        /// <summary>
        /// 按条件删除数据
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        int Delete(Expression<Func<T, bool>> whereExpression);
    }
}
